/*
 *  Cero Project - Copyright   2006 The Cero Developement Team 
 *  (Michael Laguerre, Camille Roux, Matthieu Segret, Mathieu Sivade) 
 * 
 *  This program is free software; you can redistribute it and/or modify it 
 *  under the terms of the GNU General Public License as published by the Free 
 *  Software Foundation; either version 2 of the License, or (at your option) 
 *  any later version.
 * 
 *  This program is distributed in the hope that it will be useful, but 
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 *  for more details.
 */

package org.ceroproject.ui.graphical.tools.base;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.ceroproject.games.*;
import org.ceroproject.ui.graphical.tools.*;
import org.ceroproject.ui.graphical.tools.layout.*;
import org.ceroproject.ui.graphical.tools.layout.base.*;


/**
 * Graphical appearance of the game's deck
 * 
 * @author Matt
 */
public class DeckBase extends Deck {

	/* -------------- field ------------- */

	/** Deck's layout */
	protected DeckLayout deckLayout;
	
	/** Current card */
	protected Card currentCard;
	
	/** Color of deck backGround */
	private Color colorBackGround;
	
	/** HashMap stocking the Graphical Zones for this game */
	protected HashMap<Zone,GraphicsZone> graphicsZoneMap = new HashMap<Zone,GraphicsZone>();
	
	/** serialVersionUID required for serializable interface */
	private static final long serialVersionUID = -3070797052596520255L;

	
	/* ----------- Constructor ---------- */

	/**
	 * Create a Deck
	 * 
	 * @param DeckLayout
	 *            the layout that configure the deck
	 */
	public DeckBase() {
		this.deckLayout = new DeckLayoutBase();
		this.colorBackGround = Color.WHITE;
	}
	
	/**
	 * Create a Deck
	 * 
	 * @param deckLayout
	 *            the layout that configures the deck
	 */
	public DeckBase(DeckLayout deckLayout) {
		
		this();
		this.deckLayout = deckLayout;
	}

	/* ------------- Methods ------------- */
	
	
	/**
	 * Return the Deck Layout
	 * 
	 * @return the deckLayout
	 */
	public DeckLayout getDeckLayout() {
		return deckLayout;
	}

	
	/**
	 * Define the layout of this deck
	 * 
	 * @param deckLayout
	 *            the deckLayout to modify
	 */
	public void setDeckLayout(DeckLayout deckLayout) {
		this.deckLayout = deckLayout;
	}

	
	/**
	 * Change a layoutZone of a Graphical Zone
	 * 
	 * @param gZone
	 *            Graphical Zone the Zonelayout have to change
	 * @param zoneLayout
	 *            ZoneLayout which specifies how graphical cards are displayed
	 */
	public void setZoneLayout(GraphicsZone gZone, ZoneLayout zoneLayout) {
		gZone.setZoneLayout(zoneLayout);
	}
	
	
	/**
	 * Get the graphical zone associated with the specified zone
	 * 
	 * @param zone the zone associated with the graphical zone
	 */
	public GraphicsZone getGZone(Zone zone){
		return graphicsZoneMap.get(zone);
	}
	
	
	/**
	 * Get the graphical zones list
	 * 
	 * @return the graphical zones list
	 */
	public List<GraphicsZone> getGraphicsZoneList() {
		List<GraphicsZone> gZones = new ArrayList<GraphicsZone>(graphicsZoneMap.values());
		return gZones;
	}
	
	
	/**
	 * Add a Zone to the Deck
	 * 
	 * @param gZone
	 *            the Graphical Zone to add
	 */
	public void add(GraphicsZone gZone) {

		// add the graphicszone to graphicsZoneList
		graphicsZoneMap.put(gZone.getZone(),gZone);

		// put ZoneLayoutSide by default
		if (gZone.getZoneLayout() == null)
			gZone.setZoneLayout(new ZoneLayoutSide());
	}



	/**
	 * Recover update image
	 * 
	 * @param img
	 *            the image being observed.
	 * @param infoflags
	 *            the bitwise inclusive OR of the following flags: WIDTH,
	 *            HEIGHT, PROPERTIES, SOMEBITS, FRAMEBITS, ALLBITS, ERROR,
	 *            ABORT.
	 * @param x
	 *            the x coordinate.
	 * @param y
	 *            the y coordinate.
	 * @param width
	 *            the width.
	 * @param height
	 *            the height.
	 */
	public boolean imageUpdate(Image img, int infoflags, int x, int y,
			int width, int height) {
		super.imageUpdate(img, infoflags, x, y, width, height);
		
		if ((ImageObserver.ALLBITS & infoflags) != 0) {
			this.repaint();
			return false;
		}
		return true;
	}
	
	
	/**
	 * Set the background color
	 * 
	 * @param colorBackGround the color to set
	 */
	public void setbackGroundSelected(Color colorBackGround){
		this.colorBackGround = colorBackGround;
	}
	
	
	/**
	 * Paint the Deck background
	 * 
	 * @param g
	 *            Graphics needed to paint the background
	 */
	public void paintBackGround(Graphics g) {
		g.setColor(colorBackGround);
		g.fillRect(0, 0, this.getWidth(), this.getHeight());
	}
	
	/**
	 * Paint the Deck
	 * 
	 * @param g
	 *            Graphics needed to paint the Deck
	 */
	public void paint(Graphics g) {
		// update the graphics zone position
		deckLayout.updateGraphicsZone(this);
		
		// paint the Deck background
		paintBackGround(g);
		
		// paint all zone of the deck
		for(GraphicsZone gZone : graphicsZoneMap.values())
			gZone.paint(g,this);
	}

	public void gameStart(GameEvent e){}
	public void gameEnd(GameEvent e){}
}
